/*
 * File:   Juego.cpp
 * Author: MRUBACH
 *
 * Created on 30 de septiembre de 2009, 14:26
 */

#include <ios>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <vector>
#include <Juego.h>
#include <limits>

using namespace std;

Juego::Juego() {
    this->dicCargado = false;
    this->diccionario = "";
    this->puntos = 0;
    this->puntajes.clear();

}

/*Juego::PressEnterToContinue()  {
  std::cout << "Presione [ENTER] para continuar... " << flush;
  std::cin.ignore( std::numeric_limits <std::streamsize> ::max(), '\n' );
  }*/

//*********************************************************
//Constructor por default de la clase
//*********************************************************
Juego::Juego(const Juego& orig) {
}

//*********************************************************
//Destructor por default de la clase
//*********************************************************
//Juego::~Juego() {
//}

//*********************************************************
//permite a un jugador elegir el diccionario de palabras
//válidas que quiere usar en su sesión (por ejemplo,
//Castellano, Inglés, Francés).
//*********************************************************
void Juego::Inicializar(string archivo) {
    string noimporta;
   // this->puntos = 0;
    if (this->diccionario == ""){
        this->diccionario = archivo;

        ifstream file (archivo.c_str(), ios::in);

        if(!file.is_open())
        {
            cout << "No se pudo leer el archivo " << archivo << "!"<<endl;
            cout << "Presione [1 + ENTER] para continuar... " << flush;
            cin >> noimporta;
        }
        else
        {
            cout << "Leyendo archivo " << archivo << "!"<<endl;

            string linea;

            this->palabras.clear();

            while (getline(file,linea))
            {
                //Paso la palabra a mayuscula para luego compararla con la patente
                for(int i = 0; i < linea.length(); i++){
                    linea[i] = toupper(linea[i]);
                }
                this->palabras.push_back(linea);
            }

            file.close();

            if(this->palabras.size() > 0)
                this->dicCargado = true;
            else
                this->dicCargado = false;

            cout << "Carga de diccionario completa!" << endl;
            cout << "Presione [1 + ENTER] para continuar... " << flush;
            cin >> noimporta;

        }
    }
    else {
        printf("Error: El juego ya fue inicializado");
    }
    
}

//*********************************************************
//establece el conjunto de tres letras de la sesión
//*********************************************************
void Juego::Configurar(string conj_letras, int jugadores) {
    char a;
    string palabraActual = "";
    int posPrimLetraPatente = -1;
    int posSegLetraPatente = -1;
    int posTerLetraPatente = -1;

  //******************************************************
  // Establecer el nro de jugadores e inicializar vector
  //******************************************************
    for (int i=1; i <= jugadores; i++){
        this->puntajes.push_back(0);
    }
  //******************************************************
  // Fin de establecer el nro de jugadores e inicializar vector
  //******************************************************

    if (this->letras == ""){
        //Paso la patente a mayuscula
        for(int j = 0; j < conj_letras.length(); j++){
            conj_letras[j] = toupper(conj_letras[j]);
        }
        this->letras = conj_letras;

        //Recorro el diccionario
        for(int i=0; i < this->palabras.size(); i++){
            //Obtengo la palabra actual
            palabraActual = this->palabras[i];

            //Si la palabra tiene menos de 3 letras
            //ni la comparo porque no va
            if(palabraActual.length() > 2){
                //Traigo la posicion de la primer letra de la patente
                posPrimLetraPatente = palabraActual.find_first_of(this->letras[0]);
                //Si la posicion esta entre 0 y la cantidad de letras de la palabra, es porque la contiene
                if(posPrimLetraPatente >= 0 && posPrimLetraPatente < palabraActual.length()){
                    //Traigo la posicion de la segunda letra de la patente
                    posSegLetraPatente = palabraActual.find_first_of(this->letras[1]);
                    //Si la posicion esta entre 0 y la cantidad de letras de la palabra, es porque la contiene
                    if(posSegLetraPatente >= 0 && posSegLetraPatente < palabraActual.length()){
                        //Traigo la posicion de la tercera letra de la patente
                        posTerLetraPatente = palabraActual.find_first_of(this->letras[2]);
                        //Si la posicion esta entre 0 y la cantidad de letras de la palabra, es porque la contiene
                        if(posTerLetraPatente >= 0 && posTerLetraPatente < palabraActual.length()){
                            //Si llega aca es porque contiene a las 3 letras de la patente
                            //ahora me fijo el orden en que aparecen las letras
                        if(posPrimLetraPatente < posSegLetraPatente && posSegLetraPatente < posTerLetraPatente && posPrimLetraPatente < posTerLetraPatente){
                                //Si entra es porque el orden es correcto. Cargo el diccionario del juego.
                                this->palabrasParaJugar.push_back(palabraActual);
                            }
                        }
                    }
                }
            }
        }
    }
    else {
        printf("Error: El juego ya fue configurado.");
    }
}

//*********************************************************
//permite a un jugador en una sesión consultar si la
//palabra contiene el conjunto actual de letras en orden y
//también si la palabra es válida. Cuando una consulta esté
//ok, el jugador recibe un punto. Si la consulta está mal,
//pierde un punto.
//*********************************************************
bool Juego::Consulta(string palabra, int jugador) {
    int j = 0;
    bool encontro,repetida,identico = false;

    //Paso la palabra a buscar a mayuscula
    for(int i = 0; i < palabra.length(); i++){
        palabra[i] = toupper(palabra[i]);
    }

///////////////////////////
    //Recorro el el arreglo con las plabaras jugadas y verifico
    //a) que no haya repetidas --> Elegir nueva patente, pierde el turno
    //b) que no se hayan dicho ya todas las palabras -->SALIR


    j=0;
    while (j < this->palabrasJugadas.size() && !repetida){
        if(this->palabrasJugadas[j].find(palabra) >= 0 && this->palabrasJugadas[j].find(palabra) < palabra.length())
        {
         repetida = true;
         cout << "REPETIDA \n";
        }
        j++;
    }

    if ( !repetida ) {
//////////////////////////
        j = 0;
        //Recorro el el arreglo con las plabaras para jugar
        while (j < this->palabrasParaJugar.size() && !encontro){
            if(this->palabrasParaJugar[j].find(palabra) >= 0 && this->palabrasParaJugar[j].find(palabra) < palabra.length())
            {
             encontro = true;
             
             this->puntos++;
             this->puntajes[jugador-1]= this->puntajes[jugador-1] + 1;
             this->palabrasJugadas.push_back(palabra); //lleva registro de palabras válidas juagdas


                //Verifico que no se hayan ingresado todas las palabras válidas
                if (this->palabrasParaJugar.size() == this->palabrasJugadas.size()) {
                    identico = true;
                }
            }else{
                this->puntos--; // = this->puntos - 1;
                this->puntajes[jugador-1]= this->puntajes[jugador-1] - 1;
            }

            j++;
        }

    }
    return encontro;
}

//*********************************************************
//Lista todas las palabras en el diccionario que valen para
//el conjunto actual.
//*********************************************************
void Juego::Listar() {
    for(int i=0; i < this->palabrasParaJugar.size(); i++){
        cout << i <<") " << this->palabrasParaJugar[i] << endl;
    }
/*

        for(int i=0; i < this->palabrasJugadas.size(); i++){
        cout << i <<") " << this->palabrasJugadas[i] << endl;
    }
*/
}

//*********************************************************
//Devuelve los resultados obtenidos para todos los
//jugadores en un juego. Usa una secuencia de estructuras
//que contienen la información de lo jugado por cada jugador.
//*********************************************************
void Juego::Resultado() {
    /*-->recorrer "this->jugadas" que es una lista de las
         jugadas realizadas conteniendo: palabra, jugador, puntos*/
    string noImporta;

    //cout << this->puntos << endl;
    printf (" ************ \n");
    printf (" * PUNTAJES * \n");
    printf (" ************ \n\n\n");

    for (int i=0; i < this->puntajes.size(); i++){
      printf ("Jugador %d \n Puntaje acumulado: %d \n\n", i+1, this->puntajes[i]);
    }
    cin >> noImporta;
}

//*********************************************************
//Se informa al servidor que el cliente ya terminó de jugar.
//Si es el último grupo de jugadores, también se saldrá de
//la aplicación.
//*********************************************************
void Juego::Quit() {
//mandar msg al servidor
}

bool Juego::diccionarioCargado(){
    printf ("Valor de dicCargado: %d \n", this->dicCargado);
    return this->dicCargado;
}